<!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

    <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />

    <style>
        body {
            padding-left: 75px;
            background-color: beige
        }
    </style>

    <script>

        /////////////////////////// 

        //base64编码的GIF图像解码 

        //By Mozart0 

        //2005/10/29 

        //////////////////// 



        //建立GIF类的对象 

        //类GIF在此函数内部定义 

        //str64：gif文件的Base64编码字符串 

        //成功返回创建的GIF对象 

        //失败返回null 

        function getGif(str64) {

            var bytes = decodeBase64(str64);

            if (!bytes) {

                alert("错误：无效的Base64编码");

                return null;

            }

            var gif = new GIF();

            for (var i = 0; i < 6; i++)

                gif.version += String.fromCharCode(bytes[i]);

            if (gif.version.slice(0, 3) != "GIF") {

                alert("错误：非Gif图像格式");

                return null;

            }

            gif.width = bytes[i] | (bytes[i + 1] << 8);

            gif.height = bytes[i + 2] | (bytes[i + 3] << 8);

            var f = bytes[i + 4];

            gif.colorResolution = (f >> 4 & 0x7) + 1;

            gif.sorted = (f & 0x8) ? true : false;

            gif.backgroundIndex = bytes[i + 5];

            gif.pixelAspectRadio = bytes[i + 6];

            if (f & 0x80) {

                gif.globalPalette = [];

                i += getPalette(i + 7, bytes, gif.globalPalette, 2 << (f & 0x7));

            }

            i += 7;

            for (var j = i; j < bytes.length; j++)

                if (bytes[j] == 0x21 && bytes[j + 1] == 0xf9)

                    break;

            if (j == bytes.length) {

                for (; i < bytes.length; i++)

                    if (bytes[i] == 0x2c)

                        break;

                if (i == bytes.length) {

                    alert("错误：找不到图像数据");

                    return null;

                }

                var f = new GIF_Frame();

                if (!getSingleFrame(i, f))

                    return null;

                else

                    gif.frames.push(f);

            }

            else {

                i = j;

                do {

                    var f = new GIF_Frame();

                    var t = getSingleFrame(i, f);

                    if (!t)

                        return null;

                    gif.frames.push(f);

                    for (i += t; i < bytes.length; i++)

                        if (bytes[i] == 0x21 && bytes[i + 1] == 0xf9)

                            break;

                }

                while (i < bytes.length);

            }

            return gif;



            //内部过程，生成色表 

            function getPalette(pos, s, d, len) {

                len *= 3;

                for (var i = pos; i < pos + len; i += 3)

                    d.push('#' + (s[i] <= 0xf ? "0" : "") + s[i].toString(16)

                        + (s[i + 1] <= 0xf ? "0" : "") + s[i + 1].toString(16)

                        + (s[i + 2] <= 0xf ? "0" : "") + s[i + 2].toString(16));

                return len;

            }



            //内部过程，整合数据段 

            function getBlock(pos, s, d) {

                var p = pos;

                while (len = s[p++]) {

                    for (var i = 0; i < len; i++)

                        d.push(s[p + i]);

                    p += len;

                }

                return p - pos;

            }



            //内部过程，获取一帧数据 

            function getSingleFrame(pos, frame) {

                var i = pos;

                if (bytes[i] == 0x21) {

                    i += 3;

                    if (bytes[i] & 1)

                        frame.transparentIndex = bytes[i + 3];

                    frame.delay = bytes[i + 1] | (bytes[i + 2] << 8);

                    for (i += 5; i < bytes.length && bytes[i] != 0x2c; i++);

                    if (i == bytes.length) {

                        alert("错误:找不到图像标志符");

                        return 0;

                    }

                }

                frame.offsetX = bytes[i + 1] | (bytes[i + 2] << 8);

                frame.offsetY = bytes[i + 3] | (bytes[i + 4] << 8);

                frame.width = bytes[i + 5] | (bytes[i + 6] << 8);

                frame.height = bytes[i + 7] | (bytes[i + 8] << 8);

                var f = bytes[i + 9];

                i += 10;

                if (f & 0x40)

                    frame.interlace = true;

                if (f & 0x20)

                    frame.sorted = true;

                if (f & 0x80) {

                    frame.colorResolution = (f & 0x7) + 1;

                    frame.localPalette = [];

                    i += getPalette(i, bytes, frame.localPalette, 1 << frame.colorResolution);

                }

                else {

                    frame.colorResolution = gif.colorResolution;

                    frame.localPalette = gif.globalPalette;

                }

                var lzwLen = bytes[i++] + 1;

                i += getBlock(i, bytes, frame.data);

                frame.data = decodeLzw(frame.data, lzwLen);

                return frame.data ? i - pos : 0;

            }



            //定义存储GIF文件的数据结构 

            //提供方法showInfo,返回图片信息 

            function GIF() {

                this.version = ""; //版本号 

                this.width = 0; //逻辑屏幕宽度 

                this.height = 0; //逻辑屏幕高度 

                this.colorResolution = 0; //颜色深度 

                this.sorted = false; //全局色表分类标志 

                this.globalPalette = null; //全局色表 

                this.backgroundIndex = -1; //背景色索引 

                this.pixelAspectRadio = 0; //像素宽高比 

                this.frames = []; //图像各帧，见GIF_Frame 

                this.showInfo = function (sep) { //显示图片信息,sep为行分隔符 

                    if (!sep)

                        sep = "\n";

                    var s = "Gif infomation:" + sep + "-------------------";

                    s += subInfo(this) + sep;

                    for (var i = 0; i < this.frames.length; i++)

                        s += sep + "frames " + i + "----------" + subInfo(this.frames[i]);

                    return s;

                    function subInfo(o) {

                        var s = "";

                        for (var i in o) {

                            if (i == "showInfo" || i == "draw")

                                continue;

                            s += sep + i + ":";

                            if (typeof (o[i]) == "object")

                                s += (o[i] ? o[i].length : "null");

                            else

                                s += o[i];

                        }

                        return s;

                    }

                }

            }



            //定义存储一帧图象的数据结构 

            //提供方法draw,绘图 

            function GIF_Frame() {

                this.offsetX = 0; //X方向偏移量 

                this.offsetY = 0; //Y方向偏移量 

                this.width = 0; //图象宽度 

                this.height = 0; //图象高度 

                this.localPalette = null; //局部色表 

                this.colorResolution = 0; //颜色深度 

                this.interlace = false; //交错标志 

                this.sorted = false; //局部色表分类标志 

                this.data = []; //图像数据，存储各像素颜色的整数索引 

                this.transparentIndex = -1; //透明色索引 

                this.delay = 0; //帧延时 

                this.draw = function (parent, zoom) {

                    if (!this.data.length)

                        return;

                    if (!parent)

                        parent = document.body;

                    if (!zoom)

                        zoom = 1;

                    if (parent.clientWidth < this.width * zoom)

                        parent.style.width = this.width * zoom;

                    if (parent.clientHeight < this.height * zoom)

                        parent.style.height = this.height * zoom;

                    var id = "ImgDefaultDraw";

                    var img = document.getElementById(id);

                    if (img)

                        delete parent.removeChild(img);

                    img = document.createElement("DIV");

                    img.id = id;

                    parent.appendChild(img);

                    img.style.position = "absolute";

                    var t = document.createElement("DIV");

                    t.style.overflow = "hidden";

                    t.style.position = "absolute";

                    defLayout(this.data, this.localPalette, this.width, this.height, img, t, zoom);

                    delete t;

                }

            }

        }



        //Base64解码 

        //strIn，输入字符串 

        //成功返回一个数组，每一个元素包含一字节信息 

        //失败返回null 

        function decodeBase64(strIn) {

            if (!strIn.length || strIn.length % 4)

                return null;

            var str64 =

                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

            var index64 = [];

            for (var i = 0; i < str64.length; i++)

                index64[str64.charAt(i)] = i;

            var c0, c1, c2, c3, b0, b1, b2;

            var len = strIn.length;

            var len1 = len;

            if (strIn.charAt(len - 1) == '=')

                len1 -= 4;

            var result = [];

            for (var i = 0, j = 0; i < len1; i += 4) {

                c0 = index64[strIn.charAt(i)];

                c1 = index64[strIn.charAt(i + 1)];

                c2 = index64[strIn.charAt(i + 2)];

                c3 = index64[strIn.charAt(i + 3)];

                b0 = (c0 << 2) | (c1 >> 4);

                b1 = (c1 << 4) | (c2 >> 2);

                b2 = (c2 << 6) | c3;

                result.push(b0 & 0xff);

                result.push(b1 & 0xff);

                result.push(b2 & 0xff);

            }

            if (len1 != len) {

                c0 = index64[strIn.charAt(i)];

                c1 = index64[strIn.charAt(i + 1)];

                c2 = strIn.charAt(i + 2);

                b0 = (c0 << 2) | (c1 >> 4);

                result.push(b0 & 0xff);

                if (c2 != '=') {

                    c2 = index64[c2];

                    b1 = (c1 << 4) | (c2 >> 2);

                    result.push(b1 & 0xff);

                }

            }

            return result;

        }



        //用于GIF的LZW解码函数 

        //arrBytes为源数据,nBits为初始编码位数 

        //成功返回数组，每个元素包括一个颜色索引 

        //失败返回null 

        function decodeLzw(arrBytes, nBits) {

            var cc = 1 << (nBits - 1);

            var eoi = cc + 1;

            var table = [], mask = [], result = [];

            for (var i = 0; i < cc; i++)

                table[i] = (i >> 8 & 0xf).toString(16)

                    + (i >> 4 & 0xf).toString(16) + (i & 0xf).toString(16);

            for (i = 2, mask[1] = 1; i < 13; i++)

                mask[i] = mask[i - 1] << 1 | 1;

            var bc = nBits;

            var pos = 0, temp = 0, tleft = 0, code = 0, old = 0;

            while (true) {

                while (tleft < bc) {

                    temp = temp | (arrBytes[pos++] << tleft);

                    tleft += 8;

                }

                code = temp & mask[bc];

                tleft -= bc;

                temp >>= bc;

                if (code == eoi)

                    break;

                if (code == cc) {

                    table.length = cc + 2;

                    bc = nBits;

                    old = code;

                    continue;

                }

                var t = "";

                if (code < table.length) {

                    t = table[code];

                    if (old != cc)

                        table.push(table[old] + t.slice(0, 3));

                }

                else if (old < table.length) {

                    t = table[old] + table[old].slice(0, 3);

                    table.push(t);

                }

                else {

                    alert("错误：图像数据无效");

                    return null;

                }

                old = code;

                for (var i = 0; i < t.length; i += 3)

                    result.push(parseInt(t.substr(i, 3), 16))

                if (table.length == 1 << bc && bc < 12)

                    bc++;

            }

            return result;

        }



        //根据字节数组data布局，以最少的div完成绘图 

        function defLayout(data, palette, width, height, image, block, zoom) {

            var map = new Array(height);

            for (var i = 0; i < height; i++) {

                map[i] = new Array(width);

                for (var j = 0; j < width; j++)

                    map[i][j] = data[i * width + j];

            }

            var i, j, i1, i2, j1, j2, c;

            for (i = 0; i < height; i++)

                for (j = 0; j < width;) {

                    if (map[i][j] == 0x100) {

                        j++;

                        continue;

                    }

                    c = map[i][j];

                    for (i1 = i + 1; i1 < height && map[i1][j] == c; i1++);

                    for (j1 = j + 1; j1 < width; j1++) {

                        for (i2 = i; i2 < i1 && map[i2][j1] == c; i2++);

                        if (i2 < i1)

                            break;

                    }

                    for (i2 = i; i2 < i1; i2++)

                        for (j2 = j; j2 < j1; j2++)

                            map[i2][j2] = 0x100;

                    var x = block.cloneNode(true);

                    x.style.left = j * zoom;

                    x.style.top = i * zoom;

                    x.style.width = (j1 - j) * zoom;

                    x.style.height = (i1 - i) * zoom;

                    x.style.backgroundColor = palette[c];

                    image.appendChild(x);

                    j = j1;

                }

        }

    </SCRIPT>



    <script>

        function main() {

            var t = new Date().getTime();

            var xmldom = document.getElementById("imgData");

            var gif = getGif("R0lGODlhDwAPAKECAAAAzMzM/////wAAACwAAAAADwAPAAACIISPeQHsrZ5ModrLlN48CXF8m2iQ3YmmKqVlRtW4MLwWACH+H09wdGltaXplZCBieSBVbGVhZCBTbWFydFNhdmVyIQAAOw==");

            var info = document.getElementById("info");

            info.innerHTML = gif.showInfo("<br>");

            t = new Date().getTime();

            gif.frames[0].draw(document.getElementById("canvas"), 1);

            info.innerHTML += "<br>绘图耗时" + (new Date().getTime() - t) + "ms";

        }

    </SCRIPT>

<body onload="main()">

    <div id="canvas"></div>

    <hr>

    <div id="info">页面载入中，请稍候...</div>

</body>

</html>